'use strict'

module.exports = core
const path = require('path')
const userHome = require('os').homedir()
const pathExists = require('path-exists').sync
const semver = require('semver')
const commander = require('commander')
const colors = require('colors/safe')
const pkg = require('../package.json')
const log = require('@kpzc-cli-dev/log')
const exec = require('@kpzc-cli-dev/exec')
const constant = require('./const')
//注册脚手架对象
const program = new commander.Command()

async function core() {
  try {
    //脚手架初始化阶段
    await prepare()
    //命令注册阶段
    registerCommand()
  } catch (e) {
    log.error(e.message)
    if (program.opts().debug) {
      console.log(e)
    }
  }
}

function registerCommand() {
  program
    .name(Object.keys(pkg.bin)[0])
    .usage('<command> [options]')
    .version(pkg.version)
    .option('-d, --debug', '是否开启debug模式', false)
    .option('-tp, --targetPath <targetPath>', '是否指定本地调试文件路径', '')
  //命令注册
  program
    .command('init [projectName]')
    .option('-f, --force', '是否强制初始化项目')
    .action(exec)
  program
    .command('publish')
    .option('--refershServer', '强制跟新远程Git仓库')
    .option('--refershToken', '强制跟新远程仓库token')
    .option('--refershOwner', '强制跟新远程仓库类型')
    .option('--buildCmd <buildCmd>', '构建命令')
    .option('--prod', '是否正式发布')
    .option('--sshUser <sshUser>', '模版服务器用户名')
    .option('--sshIp <sshIp>', '模版服务器Ip地址')
    .option('--sshPath <sshPath>', '模版服务器上传路径')
    .action(exec)
  program
    .command('add [templateName]')
    .option('-f, --force', '是否强制添加代码')
    .action(exec)
  //开启debug模式
  program.on('option:debug', function () {
    if (program.opts().debug) {
      process.env.LOG_LEVEL = 'verbose'
    } else {
      process.env.LOG_LEVEL = 'info'
    }
    log.level = process.env.LOG_LEVEL
    log.verbose('test', 'debug...')
  })
  // 指定全局 targetPath
  program.on('option:targetPath', function () {
    process.env.CLI_TARGET_PATH = program.opts().targetPath
  })
  //对未知命令的监听
  program.on('command:*', function (cmdObj) {
    const availableCmds = program.commands.map((cmd) => cmd.name)
    console.log(colors.red('未知命令:' + cmdObj[0]))
    if (availableCmds.length > 0) {
      console.log(colors.green('可用命令:' + availableCmds.join(',')))
    }
  })
  program.parse(process.argv)
  //用户没有传参数打印帮助信息
  if (program.args && program.args.length < 1) {
    program.outputHelp()
    console.log()
  }
}

async function prepare() {
  checkPkgVersion()
  checkRoot()
  checkUserHome()
  checkEnv()
  await checkGlobalUpdate()
}
async function checkGlobalUpdate() {
  //1. 获取当前的版本号模块名
  const currentVersion = pkg.version
  const npmName = pkg.name
  const { getNpmSemverVersions } = require('@kpzc-cli-dev/get-npm-info')
  const lastVersions = await getNpmSemverVersions(currentVersion, npmName)
  if (lastVersions && semver.gt(lastVersions, currentVersion)) {
    log.warn(
      '更新提示:',
      colors.yellow(`请手动更新 ${npmName}, 当前版本:${currentVersion},最新版本:${lastVersions},
        更新命令：npm install -g ${npmName}`)
    )
  }
  //2. 通过npm Api，获取所有的版本号
  //3. 获取所有版本号，比对那些版本号大于当前版本
  //4. 获取最新版本号，提示用户更新到该版本
}

function checkUserHome() {
  if (!userHome || !pathExists(userHome)) {
    throw new Error(colors.red('当前登录用户主目录不存在！'))
  }
}

function checkEnv() {
  const dotenv = require('dotenv')
  const dotenvPath = path.resolve(userHome, '.env')
  if (pathExists(dotenvPath)) {
    dotenv.config({
      path: dotenvPath
    })
  }
  //环境变量不存在的时候，创建
  createDefaultConfig()
}

function createDefaultConfig() {
  const cliConfig = {
    home: userHome
  }
  if (process.env.CLI_HOME) {
    cliConfig['cliHome'] = path.join(userHome, process.env.CLI_HOME)
  } else {
    cliConfig['cliHome'] = path.join(userHome, constant.DEFAULT_CLI_HOME)
  }
  process.env.CLI_HOME_PATH = cliConfig.cliHome
}

function checkPkgVersion() {
  log.notice('cli', pkg.version)
}

function checkRoot() {
  const rootCheck = require('root-check')
  rootCheck()
}
